/*
 * Copyright (c) 2009, Manish Shakya,Real Time Solutions Pvt. Ltd.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the Institute nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *
 */
/**
*
*	\file	uart0.c
*	\author Manish Shakya 
*	\brief
*	\date  Tuesday,October 27,2009
*	\version 1.0
*
*
*/
#include "peripherals.h"
#ifdef __UART0__

	#if WARNING_ENABLE == 1
		#warning "Please Check PLL Settings and Baudrate Reload Value"
	#endif

	#if UART0_DEBUG == 1
		#define UART0_INTERRUPT 		0
		#define UART0_INTERRUPT_TX 		0
		#define UART0_INTERRUPT_RX 		0
		#define UART0_INTERRUPT_ERROR 	0
	#endif

	 	
		#ifndef UART0_BAUDRATE
			#warning "Please define UART0 Baudrate"
		#endif
		
		#ifndef UART0_CONTROL
			#warning "Please define UART0 databits,parity..etc"
		#endif
#if UART0_INTERRUPT == 1 
/***********************************************************************************************************************/
 __irq void 
 __uart0_isr(void)
{
   		unsigned char c;
   		c=U0IIR;
		
		#if UART0_INTERRUPT_TX==1
		if(c&0x02){
			uart0_tx_isr();
		}
		#endif
	
		/*error in serial comm*/
		#if UART0_INTERRUPT_ERROR ==1
		if(U0LSR &0x80){
			uart0_error_isr();
			c=U0RBR;
		}
		#endif
		
		/*char to received*/
		#if UART0_INTERRUPT_RX == 1
		if(U0LSR&0x01){
			c=U0RBR;
			uart0_rx_isr(c);
		}
		#endif

		VICVectAddr=0x000000000;
}
#endif

/***********************************************************************************************************************/

void
uart0_init()
{
		
		#ifndef  UART0_CONTROL
			#error "Define UART0_CONTROL in app-config.h"
		#endif

		#ifndef UART0_BAUDRATE
			#error "Define UART0_BAUDRATE in app-config.h"
		#endif


		PINSEL0|=0x00000005;/*enable serial upins*/; /*select Txd and RXd Pin*/         
		U0LCR 	= UART0_CONTROL|0x80;         /* 8 bits, no Parity, 1 Stop bit     */
	  	U0DLL 	= (unsigned char)(UART0_BAUDRATE&0x00FF); 
  	  	U0DLM 	= (unsigned char)((UART0_BAUDRATE&0xFF00)>>8); 
	  	U0LCR 	= UART0_CONTROL;        /* DLAB = 0  */ 

		#if UART0_DEBUG == 0
		#if UART0_INTERRUPT== 1
			#if	UART0_INTERRUPT_RX== 1
			U0IER		|=	0x1;			/* Enable receive int */
			#endif
			#if	UART0_INTERRUPT_TX== 1
			U0IER		|=	0x2;			/* Enable receive int */
			#endif
			#if	UART0_INTERRUPT_ERROR== 1
			U0IER		|=	0x4;			/* Enable receive int */
			#endif

			irq_install(UART0_INT,__uart0_isr);
		#endif
		#endif
}


#if UART0_INTERRUPT_TX == 0 
/***********************************************************************************************************************/
char
uart0_put_char(char c)
{
    U0THR=c;

    while (!(U0LSR&0x20)); 
    /*check transmitter hold register is empty or not*/
    return c;
}

/***********************************************************************************************************************/
void 
uart0_put_str(char * str)
{
    while (*str)    {
        uart0_put_char(*str);
        ++str;
    }
}

/***********************************************************************************************************************/
void
uart0_put(void * str,uint32_t len)
{
	uint8_t *ptr=str;

	for(;len>0;--len)
	{
		uart0_put_char(*ptr);
		++ptr;
	}
}
#endif

#if UART0_INTERRUPT_RX == 0
/***********************************************************************************************************************/
unsigned char 
uart0_char()
{
	return (U0LSR&0x01);
}

/***********************************************************************************************************************/
unsigned char 
uart0_get_char()
{
    unsigned char c;
    while (!(U0LSR&0x01));
    c=U0RBR;
    return c;
}
#endif

#if UART0_DEBUG == 1

#include <stdio.h>
#include <rt_misc.h>

#pragma import(__use_no_semihosting_swi)

struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;


int fputc(int ch, FILE *f) {
  return (uart0_put_char(ch));
}


int ferror(FILE *f) {
  /* Your implementation of ferror */
  return EOF;
}


void _ttywrch(int ch) {
  uart0_put_char(ch);
}


void _sys_exit(int return_code) {
label:  goto label;  /* endless loop */
}


#endif
#endif
